import java.util.ArrayList;
import akka.actor.*;

/**
 * 
 * @author Pietro Bua & Rohmin Mirza
 *
 */
public class Secretary extends UntypedActor
{
	private ArrayList<ActorRef> waitingDevelopers, waitingCustomers;
	private final ActorRef leader;
	private Boolean leaderAvailable;

	/**
	 * 
	 * @param lead
	 */
	public Secretary(ActorRef lead)
	{
		leader = lead;
	}
	
	/**
	 * 
	 */
	@Override
	public void preStart()
	{
		System.out.println(">Secretary actor started");
		waitingDevelopers = new ArrayList<ActorRef>();
		waitingCustomers = new ArrayList<ActorRef>();
		leaderAvailable = true;
	}
	
	/**
	 * 
	 */
	@Override
	public void onReceive(Object message) throws Exception
	{
		if( message instanceof Message )
		{
			Message m = (Message) message;
			switch(m)
			{
				case REQUEST_MEETING_DEV:
					if(leaderAvailable == true)
					{
						waitingDevelopers.add(getSender());

						if(waitingDevelopers.size()>=1 && waitingCustomers.size()>=1) 
						{
							ActorRef firstDev = waitingDevelopers.get(0);
							CustomerMeeting cm = new CustomerMeeting((ArrayList<ActorRef>) waitingCustomers.clone(),firstDev);

							waitingDevelopers.remove(firstDev);
							for (ActorRef devs : waitingDevelopers) 
							{
								devs.tell(Message.MEETING_END, getSelf());
							}
							waitingDevelopers.clear();
							waitingCustomers.clear();
							leader.tell(cm, getSelf());
							leaderAvailable=false;
						} 
						else if(waitingDevelopers.size()==3) 
						{
							DeveloperMeeting dm = new DeveloperMeeting((ArrayList<ActorRef>) waitingDevelopers.clone());
							leader.tell(dm, getSelf());
							waitingDevelopers.clear();
							leaderAvailable=false;
						}
					} 
					else if(leaderAvailable == false)
					{
						getSender().tell(Message.MEETING_END, getSelf());
					}
					break;
				case REQUEST_MEETING_CUS:
					waitingCustomers.add(getSender());
					if(waitingDevelopers.size()>=1 && waitingCustomers.size()>=1 && leaderAvailable == true) 
					{
						CustomerMeeting cm = new CustomerMeeting((ArrayList<ActorRef>) waitingCustomers.clone(),waitingDevelopers.get(0));
						waitingDevelopers.remove(waitingDevelopers.get(0));

						for (ActorRef devs : waitingDevelopers) 
						{
							devs.tell(Message.MEETING_END, getSelf());
						}		
						waitingCustomers.clear();
						leader.tell(cm, getSelf());
						leaderAvailable=false;
					}
					break;
				case MEETING_DONE:
					System.out.println("Leader is available again because meeting is done");
					leaderAvailable = true;
					break;
				default:unhandled(m);
			}
		}
	}
	
	/**
	 * 
	 */
	public void postStop()
	{
		System.out.println("<Secretary actor exiting");
	}	

	/**
	 * 
	 * @param leader
	 * @return
	 */
	public static Props prop(ActorRef leader)
	{
		return Props.create(Secretary.class, leader);
	}


}
